using System.Security.Claims;

namespace 高校员工餐饮信息管理系统.Middleware
{
    /// <summary>
    /// 权限校验中间件
    /// 根据用户角色动态加载可访问菜单和功能
    /// </summary>
    public class RolePermissionMiddleware
    {
        private readonly RequestDelegate _next;
        private readonly ILogger<RolePermissionMiddleware> _logger;

        // 定义各角色可访问的路径
        private readonly Dictionary<string, List<string>> _rolePermissions = new()
        {
            { "教职工", new List<string> { "/", "/Order", "/Profile", "/History" } },
            { "商户", new List<string> { "/", "/Merchant/Orders", "/Merchant/Settlement", "/Merchant/Export" } },
            { "系统管理员", new List<string> { "/", "/Admin/Users", "/Admin/Merchants", "/Admin/Settings" } },
            { "部门管理员", new List<string> { "/", "/Department/Orders", "/Department/Settlement", "/Department/Export" } }
        };

        public RolePermissionMiddleware(RequestDelegate next, ILogger<RolePermissionMiddleware> logger)
        {
            _next = next;
            _logger = logger;
        }

        public async Task InvokeAsync(HttpContext context)
        {
            var path = context.Request.Path.Value ?? "";
            
            // 公共路径，无需权限验证
            if (IsPublicPath(path))
            {
                await _next(context);
                return;
            }

            // 检查用户是否已认证
            if (!context.User.Identity?.IsAuthenticated ?? true)
            {
                _logger.LogWarning("未认证用户尝试访问受保护资源: {Path}", path);
                context.Response.StatusCode = 401;
                await context.Response.WriteAsync("未授权：请先登录");
                return;
            }

            // 获取用户角色
            var userRole = context.User.FindFirst(ClaimTypes.Role)?.Value;
            var userId = context.User.Identity?.Name ?? "Unknown";
            
            if (string.IsNullOrEmpty(userRole))
            {
                _logger.LogWarning("用户角色未定义: {UserId}", userId);
                context.Response.StatusCode = 403;
                await context.Response.WriteAsync("禁止访问：用户角色未定义");
                return;
            }

            // 检查角色权限
            if (!HasPermission(userRole, path))
            {
                _logger.LogWarning(
                    "权限不足 => 用户: {UserId} | 角色: {Role} | 路径: {Path}",
                    userId,
                    userRole,
                    path
                );
                context.Response.StatusCode = 403;
                await context.Response.WriteAsync("禁止访问：权限不足");
                return;
            }

            _logger.LogInformation(
                "权限验证通过 => 用户: {UserId} | 角色: {Role} | 路径: {Path}",
                userId,
                userRole,
                path
            );

            await _next(context);
        }

        /// <summary>
        /// 判断是否为公共路径
        /// </summary>
        private bool IsPublicPath(string path)
        {
            var publicPaths = new[]
            {
                "/",
                "/Login",
                "/ForgotPassword",
                "/ResetPassword",
                "/Error",
                "/css",
                "/js",
                "/lib",
                "/favicon.ico"
            };

            return publicPaths.Any(p => path.StartsWith(p, StringComparison.OrdinalIgnoreCase));
        }

        /// <summary>
        /// 检查角色是否有权限访问指定路径
        /// </summary>
        private bool HasPermission(string role, string path)
        {
            if (!_rolePermissions.ContainsKey(role))
            {
                return false;
            }

            var allowedPaths = _rolePermissions[role];
            
            // 检查路径是否在允许列表中
            return allowedPaths.Any(p => path.StartsWith(p, StringComparison.OrdinalIgnoreCase));
        }
    }
}

